package easy.netty.net.core.ws;

import easy.netty.net.core.Endpoint;
import easy.netty.net.core.IoConf;
import easy.netty.net.core.IoHandler;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.websocketx.*;
import io.netty.util.CharsetUtil;

import java.net.URI;
import java.net.URISyntaxException;

/**
 * @author cengy
 */
public class WsClientIoHandler
        extends IoHandler {


    public WsClientIoHandler(Endpoint endpoint) {
        super(endpoint);
    }

    protected WebSocketClientHandshaker handshaker;

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {

        IoConf netConf = endpoint.getIoConf();
        // fixme: if use wss
        String uriStr = "ws://" + netConf.getIp()
                + ":" + netConf.getPort() + "/" + netConf.getWsLocation();

        URI uri = null;
        try {
            uri = new URI(uriStr);
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }

        WebSocketClientHandshaker handshaker = WebSocketClientHandshakerFactory.newHandshaker(
                uri, WebSocketVersion.V13, null, false,
                new DefaultHttpHeaders()
        );

        this.handshaker = handshaker;
        handshaker.handshake(ctx.channel());
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {

        Channel ch = ctx.channel();

        if (!handshaker.isHandshakeComplete()) {
            handshaker.finishHandshake(ch, (FullHttpResponse) msg);
            super.channelActive(ctx);
            return;
        }

        if (msg instanceof FullHttpResponse) {

            FullHttpResponse response = (FullHttpResponse) msg;
            throw new IllegalStateException(
                    "Unexpected FullHttpResponse (getStatus=" + response.getStatus() +
                            ", content=" + response.content().toString(CharsetUtil.UTF_8) + ')');
        }

        WebSocketFrame frame = (WebSocketFrame) msg;

        if (frame instanceof PongWebSocketFrame) return;

        if (frame instanceof CloseWebSocketFrame) {
            ch.close();
            return;
        }

        super.channelRead0(ctx, msg);
    }


}
